package channelAPI

import (
	"errors"
	"gitee.com/fierce_wolf/go-fox-edge-common/commRedisRpc"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/Signal"
)

type channelService struct {
	Execute       IChannelServerExecute       // 执行主从半双工操作：上位机向设备问询，并等待设备的回答，直到设备响应或者超时
	Publish       IChannelServerPublish       // 执行发布操作：上位机向设备单向发送报文，不需要等待设备的返
	Report        IChannelServerReport        // 设备的主动上报消息：设备向上位机
	OpenChannel   IChannelServerOpenChannel   // 打开通道
	CloseChannel  IChannelServerCloseChannel  // 关闭通道
	ManageChannel IChannelServerManageChannel // 对通道进行管理操作
	reportSignal  *Signal.Lock
}

func (e *channelService) execute(requestVO *commRedisRpc.ChannelRequestVO) (*commRedisRpc.ChannelRespondVO, error) {
	if e.Execute == nil {
		return nil, errors.New("该channel不支持主从问答方式")
	}
	return e.Execute.Execute(requestVO)
}

func (e *channelService) publish(requestVO *commRedisRpc.ChannelRequestVO) error {
	if e.Publish == nil {
		return errors.New("该channel不支持Publish方式")
	}
	return e.Publish.Publish(requestVO)
}

func (e *channelService) NotifyReport() {
	e.reportSignal.Signal()
}

func (e *channelService) GetReports() ([]*commRedisRpc.ChannelRespondVO, error) {
	if e.Report == nil {
		return nil, errors.New("该channel不支持Publish方式")
	}

	// 等待取上报数据的信号
	e.reportSignal.Wait()

	// 取上报数据
	return e.Report.Report()
}

func (e *channelService) openChannel(channelName string, channelParam map[string]interface{}) error {
	if e.OpenChannel == nil {
		return errors.New("该channel不支持OpenChannel")
	}

	return e.OpenChannel.OpenChannel(channelName, channelParam)
}

func (e *channelService) closeChannel(channelName string, channelParam map[string]interface{}) error {
	if e.CloseChannel == nil {
		return errors.New("该channel不支持CloseChannel")
	}

	return e.CloseChannel.CloseChannel(channelName, channelParam)
}

func (e *channelService) manageChannel(requestVO *commRedisRpc.ChannelRequestVO) (*commRedisRpc.ChannelRespondVO, error) {
	if e.ManageChannel == nil {
		return nil, errors.New("该channel不支持CloseChannel")
	}

	return e.ManageChannel.ManageChannel(requestVO)
}
